using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class JSON {
	private string data = "";
	private Dictionary<string, string> members = new Dictionary<string, string>();
	
	public JSON() {}
	
	public JSON(string json) {
		// Trim any unwanted characters.
		string copy = json.Trim();
		
		// Remove first and last character.
		copy = copy.Substring(1, copy.Length - 2);
		
		// Go through all members.
		string[] members = copy.Split(',');
		foreach (string member in members) {
			string m = member.Trim();
			string[] pair = m.Split(':');
			
			// Make sure the line consists of exactly one variable and one value.
			if (pair.Length != 2) {
				Debug.LogError ("Received malformed JSON string.");
			} else {
				pair[0] = pair[0].Trim();
				pair[1] = pair[1].Trim();
				
				this.members.Add(pair[0], pair[1]);
			}
		}
	}
	
	public string build() {
		return "{" + data + "}";
	}
	
	public JSON setInt(string member, int val) {
		leadingComma(data.Length);
		data += member + " : " + packInt(val);
		return this;
	}
	
	public JSON setFloat(string member, float val) {
		leadingComma(data.Length);
		data += member + " : " + packFloat(val);
		return this;
	}
	
	public JSON setVector3(string member, Vector3 val) {
		leadingComma(data.Length);
		data += member + " : " + packVector3(val);
		return this;
	}
	
	public JSON setList<T>(string member, List<T> list, System.Func<T, string> packer) {
		leadingComma(data.Length);
		data += member + " : [";
		for (int i = 0; i < list.Count; i++) {
			leadingComma(i);
			data += packer(list[i]);
		}
		data += "]";
		return this;
	}

	public int getInt(string member) {
		return unpackInt(members[member]);
	}
	
	public float getFloat(string member) {
		return unpackFloat(members[member]);
	}
	
	public Vector3 getVector3(string member) {
		return unpackVector3(members[member]);
	}
	
	public List<T> getList<T>(string member, System.Func<string, T> unpacker) {
		string str = stripContainer(members[member]);
		string[] vars = str.Split(',');
		
		List<T> result = new List<T>();
		foreach (string element in vars) {
			result.Add(unpacker(element));
		}
		
		return result;
	}
	
	private void leadingComma(int i) {
		if (i > 0) {
			data += ", ";
		}
	}

	// Static functions
	
	private static string stripContainer(string str) {
		string trimmed = str.Trim();
		if (trimmed.Length > 2) {
			return trimmed.Substring(1, trimmed.Length - 2).Trim();
		} else return "";
	}
	
	public static string packInt(int val) {
		return "\"" + val + "\"";
	}
	
	public static string packFloat(float val) {
		return "\"" + val + "\"";
	}
	
	public static string packVector3(Vector3 val) {
		return "[\"" + val.x + "\", \"" + val.y + "\", \"" + val.z + "\"]";
	}
	
	public static int unpackInt(string val) {
		return int.Parse(stripContainer(val));
	}
	
	public static float unpackFloat(string val) {
		return float.Parse(stripContainer(val));
	}
	
	public static Vector3 unpackVector3(string val) {
		string str = stripContainer(val);
		string[] vars = str.Split(',');
		Vector3 result = new Vector3(
			float.Parse(stripContainer(vars[0])),
			float.Parse(stripContainer(vars[1])),
			float.Parse(stripContainer(vars[2]))
		);
		return result;
	}
}
